package cn.com.winning.ecare.activity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.xml.sax.InputSource;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources.NotFoundException;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;
import cn.com.winning.ecare.utils.DisplayUtil;
import cn.com.winning.ecare.utils.ParseXmlService;
import cn.com.winning.ecare.utils.URLUtils;

/**apk更新-下载-安装
 * @author coolszy
 * @date 2012-4-26
 * @blog http://blog.92coding.com
 */

public class UpdateManager
{

	/* 下载中 */
	private static final int DOWNLOAD = 1;
	/* 下载结束 */
	private static final int DOWNLOAD_FINISH = 2;
	private static final int DOWN_ERROR = 0;
	private static final int DOWN_CANEL = 3;
	private static final int DOWN_REQUEST_ERR = 4;

	/* 保存解析的XML信息 */
	HashMap<String, String> mHashMap;
	/* 下载保存路径 */
	private String mSavePath;
	private String updateDir = null;
	private String updateFile = null;
	/* 记录进度条数量 */
	private int progress;
	/* 是否取消更新 */
	private boolean cancelUpdate = false;

	private Context mContext;
	/* 更新进度条 */
	private ProgressBar mProgress;
	private Dialog mDownloadDialog;

	private NotificationManager notificationManager;
	private Notification notification;

	private Intent updateIntent;
	private PendingIntent pendingIntent;

	private int notification_id = 0;
	DownloadApkThread downloadApkThread = null;
	private String updatecontent ="";

	private Handler mHandler = new Handler()
	{
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
			// 正在下载
				case DOWNLOAD:
					// 设置进度条位置
					mProgress.setProgress(progress);
					break;
				case DOWNLOAD_FINISH:
					// 安装文件
					// 取消下载对话框显示
					if (mDownloadDialog != null && mDownloadDialog.isShowing())
					{
						mDownloadDialog.dismiss();
					}
					installApk();
					break;
				case DOWN_ERROR:
					if (mDownloadDialog != null && mDownloadDialog.isShowing())
					{
						mDownloadDialog.dismiss();
					}
					notification.tickerText = "下载失败";
					Toast.makeText(mContext, "下载失败", Toast.LENGTH_LONG).show();
					notification.setLatestEventInfo(mContext, mHashMap.get("name"), "下载失败", pendingIntent);
					notificationManager.notify(notification_id, notification);
					break;
				case DOWN_CANEL:
					if (mDownloadDialog != null && mDownloadDialog.isShowing())
					{
						mDownloadDialog.dismiss();
					}
					notification.tickerText = "取消下载";
					notification.setLatestEventInfo(mContext, mHashMap.get("name"), "取消下载", pendingIntent);
					notificationManager.notify(notification_id, notification);
					if (downloadApkThread != null)
					{
						downloadApkThread.interrupt();
						downloadApkThread = null;
					}
					break;
				case DOWN_REQUEST_ERR:
					if (mDownloadDialog != null && mDownloadDialog.isShowing())
					{
						mDownloadDialog.dismiss();
					}
					if(notification!=null){
						notification.tickerText = "网络连接失败，请检查网络！";
						notification.setLatestEventInfo(mContext, mHashMap.get("name"), "网络连接失败，请检查网络！", pendingIntent);
						notificationManager.notify(notification_id, notification);
					}
					Toast.makeText(mContext, "网络连接失败，请检查网络！", Toast.LENGTH_LONG).show();
					if (downloadApkThread != null)
					{
						downloadApkThread.interrupt();
						downloadApkThread = null;
					}
					break;
				default:
					break;
			}
		};
	};

	Handler handler = new Handler(new Callback()
	{
		@Override
		public boolean handleMessage(Message msg)
		{
			contentView.setTextViewText(R.id.notificationPercent, msg.what + "%");
			contentView.setProgressBar(R.id.notificationProgress, 100, msg.what, false);
			// show_view
			notificationManager.notify(notification_id, notification);
			return false;
		}
	});

	public UpdateManager(Context context)
	{
		this.mContext = context;
	}

	/**
	 * 检测软件更新
	 */
	public void checkUpdate(int i)
	{
		try
		{
			if (isUpdate())
			{
				// 显示提示对话框
				showNoticeDialog();
			}
			else
			{
				if (i == 1)
				{
					Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show();
				}
			}
		}
		catch (NotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
			mHandler.sendEmptyMessage(DOWN_REQUEST_ERR);
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
			mHandler.sendEmptyMessage(DOWN_REQUEST_ERR);
		}
		catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
			mHandler.sendEmptyMessage(DOWN_REQUEST_ERR);
		}
	}

	/**
	 * 获取当前版本信息
	 * 
	 * @return
	 */
	public String findVersionName()
	{
		return getVersionName(mContext);
	}

	/**
	 * 检查软件是否有更新版本
	 * 
	 * @return
	 * @throws Exception
	 * @throws IOException
	 */
	private boolean isUpdate() throws IOException, Exception
	{
		// 获取当前软件版本
		int versionCode = getVersionCode(mContext);
		// 把version.xml放到网络上，然后获取文件信息
		// InputStream inStream = ParseXmlService.class.getClassLoader()
		// .getResourceAsStream("version.xml");
		String url = URLUtils.HOSTMAIN + "/down/version.xml";
		InputSource inStream = getVerXMLFromServer(url);
		// 解析XML文件。 由于XML文件比较小，因此使用DOM方式进行解析
		ParseXmlService service = new ParseXmlService();
		try
		{
			mHashMap = service.parseXml(inStream);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		if (null != mHashMap)
		{
			int serviceCode = Integer.valueOf(mHashMap.get("version"));
			// 版本判断
			if (serviceCode > versionCode)
			{
				updatecontent = mHashMap.get("updatecontent").toString();
				return true;
			}
		}
		
		return false;
	}

	private InputSource getVerXMLFromServer(String url) throws Exception, IOException
	{
		
		InputSource is = new InputSource();
		HttpClient client = new DefaultHttpClient();
		HttpParams httpParams = client.getParams();
		// 设置网络超时参数
		HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
		HttpConnectionParams.setSoTimeout(httpParams, 5000);
		
		HttpResponse response = client.execute(new HttpGet(url));
		HttpEntity entity = response.getEntity();
		
		if (entity != null)
		{
			String str = EntityUtils.toString(entity, "GBK");
			
            is.setCharacterStream(new StringReader(str));
		}
		return is;
	}

	/**
	 * 获取软件版本号
	 * 
	 * @param context
	 * @return
	 */
	private int getVersionCode(Context context)
	{
		int versionCode = 0;
		try
		{
			// 获取软件版本号，对应AndroidManifest.xml下android:versionCode
			versionCode = context.getPackageManager().getPackageInfo("cn.com.winning.ecare.activity", 0).versionCode;
		}
		catch (NameNotFoundException e)
		{
			e.printStackTrace();
		}
		return versionCode;
	}

	/**
	 * 获取软件版本信息
	 * 
	 * @param context
	 * @return
	 */
	private String getVersionName(Context context)
	{
		String versionName = "";
		try
		{
			// 获取软件版本号，对应AndroidManifest.xml下android:versionCode
			versionName = context.getPackageManager().getPackageInfo("cn.com.winning.ecare.activity", 0).versionName;
		}
		catch (NameNotFoundException e)
		{
			e.printStackTrace();
		}
		return versionName;
	}

	/**
	 * 显示软件更新对话框
	 */
	private void showNoticeDialog()
	{
//		// 构造对话框
//		AlertDialog.Builder builder = new Builder(mContext);
//		builder.setTitle(R.string.soft_update_title);
//		builder.setMessage(R.string.soft_update_info);
//		// 更新
//		builder.setPositiveButton(R.string.soft_update_updatebtn, new OnClickListener()
//		{
//
//			public void onClick(DialogInterface dialog, int which)
//			{
//				dialog.dismiss();
//				// 显示下载对话框
//				showDownloadDialog();
//				createNotification();
//				// downloadApk();
//			}
//		});
//		// 稍后更新
//		builder.setNegativeButton(R.string.soft_update_later, new OnClickListener()
//		{
//
//			public void onClick(DialogInterface dialog, int which)
//			{
//				dialog.dismiss();
//			}
//		});
//		Dialog noticeDialog = builder.create();
//		noticeDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
//		noticeDialog.show();
		//自定义更新窗口
		final Dialog dialog = new Dialog(mContext, R.style.MyDialog);
		dialog.setContentView(R.layout.updatecontent);
		WindowManager windowManager = ((Activity) mContext).getWindowManager();
		Display display = windowManager.getDefaultDisplay();
		int windowwidth = (int) (display.getWidth());
		int windowheight = (int) (display.getHeight());
		int contentheight = windowheight*1/2;
		
		Window mWindow = dialog.getWindow();
		WindowManager.LayoutParams lp = mWindow.getAttributes();
		lp.width = windowwidth*4/5; // 设置宽度
		lp.height = contentheight;//设置窗口高度
		mWindow.setAttributes(lp);
		
		//设置listview高度
		LinearLayout out = (LinearLayout)dialog.findViewById(R.id.updatelayout);
		LinearLayout.LayoutParams layoutp=(LinearLayout.LayoutParams)out.getLayoutParams(); 
		layoutp.height=contentheight-DisplayUtil.dip2px(mContext, 120);
		out.setLayoutParams(layoutp);
		
		TextView tv_content = (TextView)dialog.findViewById(R.id.updatecontent);
		tv_content.setText(updatecontent);
		//
		Button left = (Button) dialog.findViewById(R.id.dialog_button_ok);
		left.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				
				dialog.dismiss();
				// 显示下载对话框
				showDownloadDialog();
				createNotification();
				
			}
		});

		Button right = (Button) dialog.findViewById(R.id.dialog_button_cancel);
		right.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
			
				dialog.dismiss();
			}
		});
		dialog.show();
		
	}

	/**
	 * 显示软件下载对话框
	 */
	private void showDownloadDialog()
	{
		// 构造软件下载对话框
		AlertDialog.Builder builder = new Builder(mContext);
		builder.setTitle(R.string.soft_updating);
		// 给下载对话框增加进度条
		final LayoutInflater inflater = LayoutInflater.from(mContext);
		View v = inflater.inflate(R.layout.softupdate_progress, null);
		mProgress = (ProgressBar) v.findViewById(R.id.update_progress);
		builder.setView(v);
		// 取消更新
		builder.setNegativeButton(R.string.soft_update_cancel, new OnClickListener()
		{

			public void onClick(DialogInterface dialog, int which)
			{
				dialog.dismiss();
				// 设置取消状态
				cancelUpdate = true;
			}
		});
		mDownloadDialog = builder.create();
		mDownloadDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
		mDownloadDialog.setCanceledOnTouchOutside(false);
		mDownloadDialog.show();
		// 现在文件
		downloadApk();
	}

	/**
	 * 下载apk文件
	 */
	private void downloadApk()
	{
		// 启动新线程下载软件
		downloadApkThread = new DownloadApkThread();
		downloadApkThread.start();
	}

	/**
	 * 下载文件线程
	 * 
	 * @author coolszy
	 * @date 2012-4-26
	 * @blog http://blog.92coding.com
	 */
	private class DownloadApkThread extends Thread
	{
		@Override
		public void run()
		{
			try
			{
				int down_step = 5;// 提示step
				int totalSize;// 文件总大小
				int downloadCount = 0;// 已经下载好的大小
				int updateCount = 0;// 已经上传的文件大小
				InputStream inputStream;
				OutputStream outputStream;
				Message message;

				// 判断SD卡是否存在，并且是否具有读写权限
				if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
				{
					// 获得存储卡的路径
					String sdpath = Environment.getExternalStorageDirectory() + "/";
					mSavePath = sdpath + "download";

				}
				else
				{
					mSavePath = mContext.getDir("download", Context.MODE_WORLD_READABLE).toString();
				}

				URL url = new URL(mHashMap.get("url"));
				// 创建连接
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.connect();
				if (conn.getResponseCode() == 404)
				{
					mHandler.sendEmptyMessage(DOWN_ERROR);
				}
				// 获取文件大小
				totalSize = conn.getContentLength();
				// 创建输入流
				inputStream = conn.getInputStream();

				File file = new File(mSavePath);
				// 判断文件目录是否存在
				if (!file.exists())
				{
					file.mkdir();
				}
				File apkFile = new File(mSavePath, mHashMap.get("name"));
				outputStream = new FileOutputStream(apkFile.toString(), false);// 文件存在则覆盖掉
				byte buffer[] = new byte[1024];
				int readsize = 0;
				while ((readsize = inputStream.read(buffer)) != -1)
				{
					outputStream.write(buffer, 0, readsize);
					downloadCount += readsize;// 时时获取下载到的大小
					/**
					 * 每次增张5%
					 */
					if (updateCount == 0 || (downloadCount * 100 / totalSize - down_step) >= updateCount)
					{
						updateCount += down_step;
						progress = updateCount;
						mHandler.sendEmptyMessage(DOWNLOAD);
						message = handler.obtainMessage();
						message.what = updateCount;
						// 更新进度
						handler.sendMessage(message);
					}
					if (cancelUpdate)
					{
						break;
					};// 点击取消就停止下载.

				}
				if (cancelUpdate)
				{
					mHandler.sendEmptyMessage(DOWN_CANEL);
				}
				else
				{
					mHandler.sendEmptyMessage(DOWNLOAD_FINISH);
				}

				outputStream.close();
				inputStream.close();
			}
			catch (Exception e)
			{
				e.printStackTrace();
				mHandler.sendEmptyMessage(DOWN_ERROR);
			}

		}
	};

	/**
	 * 安装APK文件
	 */
	private void installApk()
	{
		String permission = "666";

		try
		{
			String command = "chmod " + permission + " " + mSavePath + "/" + mHashMap.get("name");
			Runtime runtime = Runtime.getRuntime();
			runtime.exec(command);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		File apkfile = new File(mSavePath, mHashMap.get("name"));
		if (!apkfile.exists())
		{
			return;
		}
		// 通过Intent安装APK文件
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");

//		SharedPreferences settings = mContext.getSharedPreferences("yyxx_file", 0);
//		// 获得可编辑对象
//		SharedPreferences.Editor editor = settings.edit();
//		editor.clear();
//		editor.commit();
//
//		SharedPreferences usesrsettings = mContext.getSharedPreferences("users_file", 0);
//		// 获得可编辑对象
//		SharedPreferences.Editor usereditor = usesrsettings.edit();
//		usereditor.clear();
//		usereditor.commit();
		pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
		notification.tickerText = "下载成功，点击安装";
		notification.setLatestEventInfo(mContext, mHashMap.get("name"), "下载成功，点击安装", pendingIntent);

		notificationManager.notify(notification_id, notification);

		// mContext.stopService(updateIntent);

		mContext.startActivity(intent);
	}

	/***
	 * 创建通知栏
	 */
	RemoteViews contentView;

	public void createNotification()
	{
		notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
		notification = new Notification();
		notification.icon = R.drawable.e_care_72;
		// 这个参数是通知提示闪出来的值.
		notification.tickerText = "开始下载";
		notification.flags = Notification.FLAG_ONGOING_EVENT;
		//
		// updateIntent = new Intent(this, MainActivity.class);
		// pendingIntent = PendingIntent.getActivity(this, 0, updateIntent, 0);

		// 这里面的参数是通知栏view显示的内容
		// notification.setLatestEventInfo(this, app_name, "下载：0%",
		// pendingIntent);
		//
		// notificationManager.notify(notification_id, notification);

		/***
		 * 在这里我们用自定的view来显示Notification
		 */
		contentView = new RemoteViews(mContext.getPackageName(), R.layout.notification_item);
		contentView.setTextViewText(R.id.notificationTitle, "正在下载");
		contentView.setTextViewText(R.id.notificationPercent, "0%");
		contentView.setProgressBar(R.id.notificationProgress, 100, 0, false);

		notification.contentView = contentView;

		updateIntent = new Intent(mContext, Login.class);
		updateIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
		pendingIntent = PendingIntent.getActivity(mContext, 0, updateIntent, 0);

		notification.contentIntent = pendingIntent;

		notificationManager.notify(notification_id, notification);

	}

	public void closeNotification()
	{
		if (notificationManager != null)
		{
			notificationManager.cancel(notification_id);
		}

	}

}
